const fs = require('fs');
const path = require('path');
const { getHeader, setHeader } = require('./helper');

module.exports = (message, env) => {
    // !== 0，说明已经处理过，直接 return
    if (message.response.status) {
        return message;
    }

    if (message.request.method !== 'GET') {
        return message;
    }

    if (message.request.path.indexOf('.') === 0) {
        message.response.status = 403;
        return message;
    }

    const requestPath = path.resolve(env.root + message.request.path);
    if (!fs.existsSync(requestPath)) {
        message.response.status = 404;
        return message;
    }

    // 判断给出的 url 是文件还是路径
    const requestPathState = fs.statSync(requestPath);
    if (requestPathState.isDirectory()) {
        // 200, directory content
        const directoryContent = fs.readdirSync(requestPath);
        let contentHTML = `<html><head><title>Index Of ${message.request.path}</title></head><body><h1>Index Of ${message.request.path}</h1><hr/><table>`
        contentHTML += directoryContent.map(item => {
        const itemPath = path.resolve(requestPath, item);
        const itemStat = fs.statSync(itemPath);
        let size = '-';
        if (itemStat.isFile()) {
            size = itemStat.size.toString();
        }
        return `<tr><td>${item}</td><td>${itemStat.mtime}</td><td>${size}</td></tr>`
        }).join('');

        contentHTML += '</table><hr/></body></html>';

        message.response.body = Buffer.from(contentHTML, 'utf-8');
        message.response.status = 200;
        return message;
    } else if (requestPathState.isFile()) {
        // 是文件

        // 判断是不是部分传
        const rangeHeader = getHeader(message.request.headers, 'Range');
        if (rangeHeader) {
            // Range: bytes=0-1
            const matchRange = rangeHeader.match(/bytes\s*=\s*(\d+)\s*-\s*(\d+)/i);
            if (matchRange) {
                const content = Buffer.alloc(matchRange[2] - matchRange[1] + 1);
                const fd = fs.openSync(requestPath, 'r+');
                // fd: 读哪个文件, content：写到哪里, 0：从哪开始写, content.length：读取多长, matchRange[1]：从文件哪里开始读
                fs.readSync(fd, content, 0, content.length, parseInt(matchRange[1]));
                fs.closeSync(fd);

                // 部分传
                message.response.body = content;
                message.response.status = 206;
                setHeader(
                    message.response.headers,
                    'Content-Range',
                    `bytes ${matchRange[1]}-${matchRange[2]}/${requestPathState.size}`);
                return message;
            }
        }

        message.response.status = 200;
        message.response.body = fs.readFileSync(requestPath);
        return message;
    } else {
        // 无法解析，返回 404
        message.response.status = 404;
        return message;
    }
}